package com.tree.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tree.backend.entity.dto.costRecord.*;
import com.tree.backend.entity.pojo.CostRecord;
import com.tree.backend.entity.vo.costRecord.CostAnalysisVO;
import com.tree.backend.entity.vo.costRecord.CostRecordVO;
import com.tree.backend.mapper.CostRecordMapper;
import com.tree.backend.service.ICostRecordService;
import com.tree.backend.service.IDepartmentService;
import com.tree.backend.service.ICostItemService;
import com.tree.backend.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 成本记录明细表 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
public class CostRecordServiceImpl extends ServiceImpl<CostRecordMapper, CostRecord> implements ICostRecordService {

    private final IDepartmentService departmentService;
    private final ICostItemService costItemService;
    private final IUserService userService;

    @Override
    public Page<CostRecordVO> getCostRecords(CostRecordQueryDTO queryDTO) {
        // 构建分页对象
        Page<CostRecord> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        
        // 使用MyBatis-Plus的条件构造器进行查询
        QueryWrapper<CostRecord> wrapper = new QueryWrapper<>();
        
        // 构建查询条件
        if (queryDTO.getRecordNo() != null && !queryDTO.getRecordNo().isEmpty()) {
            wrapper.like("record_no", queryDTO.getRecordNo());
        }
        if (queryDTO.getDepartmentId() != null) {
            wrapper.eq("department_id", queryDTO.getDepartmentId());
        }
        if (queryDTO.getCostItemId() != null) {
            wrapper.eq("cost_item_id", queryDTO.getCostItemId());
        }
        if (queryDTO.getApplicantId() != null) {
            wrapper.eq("applicant_id", queryDTO.getApplicantId());
        }
        if (queryDTO.getCostType() != null) {
            wrapper.eq("cost_type", queryDTO.getCostType());
        }
        if (queryDTO.getPaymentStatus() != null) {
            wrapper.eq("payment_status", queryDTO.getPaymentStatus());
        }
        if (queryDTO.getApprovalStatus() != null) {
            wrapper.eq("approval_status", queryDTO.getApprovalStatus());
        }
        if (queryDTO.getStartDate() != null) {
            wrapper.ge("occurrence_date", queryDTO.getStartDate());
        }
        if (queryDTO.getEndDate() != null) {
            wrapper.le("occurrence_date", queryDTO.getEndDate());
        }
        
        // 执行分页查询
        Page<CostRecord> resultPage = this.page(page, wrapper);
        
        // 转换为VO对象
        Page<CostRecordVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(resultPage.getRecords().stream().map(this::convertToVO).toList());
        
        return voPage;
    }

    @Override
    public CostRecordVO getCostRecordById(Long id) {
        CostRecord costRecord = this.getById(id);
        if (costRecord == null) {
            return null;
        }
        return convertToVO(costRecord);
    }

    @Override
    public CostRecordVO addCostRecord(CostRecordCreateDTO createDTO) {
        CostRecord costRecord = new CostRecord();
        BeanUtils.copyProperties(createDTO, costRecord);
        
        // 生成记录编号等逻辑
        costRecord.setRecordNo(generateRecordNo());
        
        this.save(costRecord);
        return convertToVO(costRecord);
    }

    @Override
    public CostRecordVO updateCostRecord(Long id, CostRecordUpdateDTO updateDTO) {
        CostRecord costRecord = this.getById(id);
        if (costRecord == null) {
            return null;
        }
        
        BeanUtils.copyProperties(updateDTO, costRecord);
        this.updateById(costRecord);
        return convertToVO(costRecord);
    }

    @Override
    public boolean deleteCostRecord(Long id) {
        return this.removeById(id);
    }

    @Override
    public CostRecordVO updateCostRecordStatus(Long id, CostRecordStatusDTO statusDTO) {
        CostRecord costRecord = this.getById(id);
        if (costRecord == null) {
            return null;
        }
        
        costRecord.setPaymentStatus(statusDTO.getPaymentStatus());
        this.updateById(costRecord);
        return convertToVO(costRecord);
    }

    @Override
    public CostRecordVO approveCostRecord(Long id, CostRecordApproveDTO approveDTO, String username) {
        CostRecord costRecord = this.getById(id);
        if (costRecord == null) {
            return null;
        }
        
        // 根据用户名查询用户信息，获取用户ID
        Long approverId = getUserIdByUsername(username);
        if (approverId == null) {
            throw new RuntimeException("无法获取当前用户信息");
        }
        
        // 设置审批信息
        costRecord.setApprovalStatus(approveDTO.getApprovalStatus());
        costRecord.setApprovalComment(approveDTO.getApprovalComment());
        costRecord.setApproverId(approverId); // 设置审批人ID
        costRecord.setApprovalTime(java.time.LocalDateTime.now());
        // 保存更新
        this.updateById(costRecord);
        return convertToVO(costRecord);
    }

    @Override
    public List<CostAnalysisVO> getCostAnalysis(CostAnalysisQueryDTO queryDTO) {
        // 使用MyBatis-Plus的条件构造器进行查询
        QueryWrapper<CostRecord> wrapper = new QueryWrapper<>();
        
        // 基础查询条件
        if (queryDTO.getDepartmentId() != null) {
            wrapper.eq("department_id", queryDTO.getDepartmentId());
        }
        if (queryDTO.getStartDate() != null) {
            wrapper.ge("occurrence_date", queryDTO.getStartDate());
        }
        if (queryDTO.getEndDate() != null) {
            wrapper.le("occurrence_date", queryDTO.getEndDate());
        }
        
        // 根据分析类型进行分组统计
        List<CostAnalysisVO> result = new ArrayList<>();
        
        // 分析类型：1-按部门 2-按成本项目 3-按时间
        Integer analysisType = queryDTO.getAnalysisType();
        if (analysisType == null) {
            analysisType = 1; // 默认为按部门分析
        }
        
        // 获取CostRecordMapper以使用更灵活的查询方式
        CostRecordMapper mapper = this.getBaseMapper();

        switch (analysisType) {
            case 1 -> { // 按部门分析
                // 使用原生SQL查询进行分组统计
                List<Map<String, Object>> departmentResults = mapper.selectMaps(wrapper.select("department_id, SUM(amount) as total")
                        .groupBy("department_id"));
                for (Map<String, Object> map : departmentResults) {
                    CostAnalysisVO vo = new CostAnalysisVO();
                    // 根据department_id获取部门名称
                    Long deptId = null;
                    Object idObj = map.get("department_id");
                    if (idObj != null) {
                        if (idObj instanceof Number) {
                            deptId = ((Number) idObj).longValue();
                        } else if (idObj instanceof String) {
                            try {
                                deptId = Long.valueOf((String) idObj);
                            }
                            catch (NumberFormatException e) {
                                // 处理转换异常
                            }
                        }
                    }
                    
                    // 获取部门名称作为name
                    if (deptId != null) {
                        try {
                            Object department = departmentService.getById(deptId);
                            if (department != null) {
                                // 假设部门实体有getDeptName方法
                                vo.setName((String) department.getClass().getMethod("getDeptName").invoke(department));
                            }
                        }
                        catch (Exception e) {
                            // 处理异常，使用ID作为名称
                            vo.setName(String.valueOf(deptId));
                        }
                    } else {
                        vo.setName("未分类");
                    }
                    
                    // 安全地设置value
                    vo.setValue(map.get("total") instanceof BigDecimal ? (BigDecimal) map.get("total") : BigDecimal.ZERO);
                    // 设置type为字符串
                    vo.setType("department");
                    result.add(vo);
                }
            }
            case 2 -> { // 按成本项目分析
                List<Map<String, Object>> costItemResults = mapper.selectMaps(wrapper.select("cost_item_id, SUM(amount) as total")
                        .groupBy("cost_item_id"));
                for (Map<String, Object> map : costItemResults) {
                    CostAnalysisVO vo = new CostAnalysisVO();
                    // 根据cost_item_id获取成本项目名称
                    Long itemId = null;
                    Object idObj = map.get("cost_item_id");
                    if (idObj != null) {
                        if (idObj instanceof Number) {
                            itemId = ((Number) idObj).longValue();
                        } else if (idObj instanceof String) {
                            try {
                                itemId = Long.valueOf((String) idObj);
                            }
                            catch (NumberFormatException e) {
                                // 处理转换异常
                            }
                        }
                    }
                    
                    // 获取成本项目名称作为name
                    if (itemId != null) {
                        try {
                            Object costItem = costItemService.getById(itemId);
                            if (costItem != null) {
                                // 假设成本项目实体有getItemName方法
                                vo.setName((String) costItem.getClass().getMethod("getItemName").invoke(costItem));
                            }
                        }
                        catch (Exception e) {
                            // 处理异常，使用ID作为名称
                            vo.setName(String.valueOf(itemId));
                        }
                    } else {
                        vo.setName("未分类");
                    }
                    
                    // 安全地设置value
                    vo.setValue(map.get("total") instanceof BigDecimal ? (BigDecimal) map.get("total") : BigDecimal.ZERO);
                    // 设置type为字符串
                    vo.setType("costItem");
                    result.add(vo);
                }
            }
            case 3 -> { // 按时间分析
                List<Map<String, Object>> timeResults = mapper.selectMaps(wrapper.select("DATE_FORMAT(occurrence_date, '%Y-%m') as date, SUM(amount) as total")
                        .groupBy("DATE_FORMAT(occurrence_date, '%Y-%m')")
                        .orderByAsc("DATE_FORMAT(occurrence_date, '%Y-%m')"));
                for (Map<String, Object> map : timeResults) {
                    CostAnalysisVO vo = new CostAnalysisVO();
                    // 安全地设置name
                    vo.setName(map.get("date") instanceof String ? (String) map.get("date") : "");
                    // 安全地设置value
                    vo.setValue(map.get("total") instanceof BigDecimal ? (BigDecimal) map.get("total") : BigDecimal.ZERO);
                    // 设置type为字符串
                    vo.setType("time");
                    result.add(vo);
                }
            }
        }
        
        return result;
    }

    @Override
    public Page<CostRecordVO> searchCostRecords(CostRecordQueryDTO queryDTO) {
        // 构建分页对象
        Page<CostRecord> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        
        // 使用MyBatis-Plus的条件构造器进行查询
        QueryWrapper<CostRecord> wrapper = new QueryWrapper<>();
        
        // 支持keyword多字段搜索
        if (queryDTO.getKeyword() != null && !queryDTO.getKeyword().isEmpty()) {
            String keyword = "%" + queryDTO.getKeyword() + "%";
            wrapper.and(w -> w
                .like("record_no", keyword)
                .or().like("description", keyword)
                .or().like("approval_comment", keyword)
            );
        }
        
        // 添加其他查询条件
        if (queryDTO.getDepartmentId() != null) {
            wrapper.eq("department_id", queryDTO.getDepartmentId());
        }
        if (queryDTO.getCostItemId() != null) {
            wrapper.eq("cost_item_id", queryDTO.getCostItemId());
        }
        if (queryDTO.getApplicantId() != null) {
            wrapper.eq("applicant_id", queryDTO.getApplicantId());
        }
        if (queryDTO.getCostType() != null) {
            wrapper.eq("cost_type", queryDTO.getCostType());
        }
        if (queryDTO.getPaymentStatus() != null) {
            wrapper.eq("payment_status", queryDTO.getPaymentStatus());
        }
        if (queryDTO.getApprovalStatus() != null) {
            wrapper.eq("approval_status", queryDTO.getApprovalStatus());
        }
        if (queryDTO.getStartDate() != null) {
            wrapper.ge("occurrence_date", queryDTO.getStartDate());
        }
        if (queryDTO.getEndDate() != null) {
            wrapper.le("occurrence_date", queryDTO.getEndDate());
        }
        
        // 执行分页查询
        Page<CostRecord> resultPage = this.page(page, wrapper);
        
        // 转换为VO对象
        Page<CostRecordVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(resultPage.getRecords().stream().map(this::convertToVO).toList());
        
        return voPage;
    }

    /**
     * 生成记录编号
     */
    private String generateRecordNo() {
        return "CR" + System.currentTimeMillis();
    }

    /**
     * 转换为VO对象
     */
    private CostRecordVO convertToVO(CostRecord costRecord) {
        CostRecordVO vo = new CostRecordVO();
        BeanUtils.copyProperties(costRecord, vo);
        
        try {
            // 填充部门名称
            if (costRecord.getDepartmentId() != null) {
                Object department = departmentService.getById(costRecord.getDepartmentId());
                if (department != null) {
                    // 假设部门实体有getDeptName方法
                    vo.setDepartmentName((String) department.getClass().getMethod("getDeptName").invoke(department));
                }
            }
            
            // 填充成本项目名称
            if (costRecord.getCostItemId() != null) {
                Object costItem = costItemService.getById(costRecord.getCostItemId());
                if (costItem != null) {
                    // 假设成本项目实体有getItemName方法
                    vo.setCostItemName((String) costItem.getClass().getMethod("getItemName").invoke(costItem));
                }
            }
            
            // 填充申请人名称
            if (costRecord.getApplicantId() != null) {
                Object applicant = userService.getById(costRecord.getApplicantId());
                if (applicant != null) {
                    // 假设用户实体有getRealName方法
                    vo.setApplicantName((String) applicant.getClass().getMethod("getRealName").invoke(applicant));
                }
            }
            
            // 填充审批人名称
            if (costRecord.getApproverId() != null) {
                Object approver = userService.getById(costRecord.getApproverId());
                if (approver != null) {
                    // 假设用户实体有getRealName方法
                    vo.setApproverName((String) approver.getClass().getMethod("getRealName").invoke(approver));
                }
            }
        } catch (Exception e) {
            // 忽略反射异常
        }
        
        // 设置枚举类型的中文名称
        vo.setCostTypeName(getCostTypeName(costRecord.getCostType()));
        vo.setPaymentStatusName(getPaymentStatusName(costRecord.getPaymentStatus()));
        vo.setApprovalStatusName(getApprovalStatusName(costRecord.getApprovalStatus()));
        
        return vo;
    }
    
    /**
     * 获取成本性质名称
     */
    private String getCostTypeName(Byte costType) {
        if (costType == null) {
            return "";
        }
        return switch (costType) {
            case 1 -> "实际成本";
            case 2 -> "预算成本";
            case 3 -> "预估成本";
            default -> "";
        };
    }
    
    /**
     * 获取支付状态名称
     */
    private String getPaymentStatusName(Byte paymentStatus) {
        if (paymentStatus == null) {
            return "";
        }
        return switch (paymentStatus) {
            case 1 -> "未支付";
            case 2 -> "已支付";
            case 3 -> "已报销";
            default -> "";
        };
    }
    
    /**
     * 获取审批状态名称
     */
    private String getApprovalStatusName(Byte approvalStatus) {
        if (approvalStatus == null) {
            return "";
        }
        return switch (approvalStatus) {
            case 1 -> "待审批";
            case 2 -> "已通过";
            case 3 -> "已驳回";
            default -> "";
        };
    }
    
    /**
     * 根据用户名查询用户ID
     * @param username 用户名
     * @return 用户ID
     */
    private Long getUserIdByUsername(String username) {
        try {
            // 使用MyBatis-Plus的条件查询直接从userService获取用户信息
            // 这里使用queryWrapper查询用户
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", username);
            Object user = userService.getOne(queryWrapper);
            
            if (user != null) {
                // 通过反射获取用户ID
                Object id = user.getClass().getMethod("getId").invoke(user);
                if (id instanceof Number) {
                    return ((Number) id).longValue();
                }
            }
        } catch (Exception e) {
            // 处理异常
            throw new RuntimeException("查询用户信息失败: " + e.getMessage(), e);
        }
        return null;
    }
}
